<template>
    <div class="uploader-file" :status="status">
        <template :file="file"
            :list="list"
            :status="status"
            :paused="paused"
            :error="error"
            :average-speed="averageSpeed"
            :formated-average-speed="formatedAverageSpeed"
            :current-speed="currentSpeed"
            :is-complete="isComplete"
            :is-uploading="isUploading"
            :size="size"
            :formated-size="formatedSize"
            :uploaded-size="uploadedSize"
            :progress="progress"
            :progress-style="progressStyle"
            :progressing-class="progressingClass"
            :time-remaining="timeRemaining"
            :formated-time-remaining="formatedTimeRemaining"
            :type="type"
            :extension="extension"
            :file-category="fileCategory">
            <div class="uploader-file-progress"
                :class="progressingClass"
                :style="progressStyle"></div>
            <div class="uploader-file-info ui flex">
                <div class="uploader-file-name item one">
                    <!--<i class="uploader-file-icon" :icon="fileCategory"></i> -->
                    <i class="file-icon icon" :class="iconClass"></i>
                    {{file.name}}
                </div>
                <div class="uploader-file-type">{{ fileType(type) }}</div>
                <div class="uploader-file-size">{{formatedSize}}</div>
                <!--<div class="uploader-file-meta"></div>-->
                <div class="uploader-file-status">
                    <span v-show="status !== 'uploading'">
                        <!--<span v-html="statusText"></span>-->
                        <el-tag size="small" :type="statusText.type">{{ statusText.text }}</el-tag>
                    </span>
                    <span v-show="status === 'uploading'">
                        <span class="t-success">{{progressStyle.progress}}</span>
                        <em class="f-12 ">({{formatedAverageSpeed}})</em>
                        <!--<i>{{formatedTimeRemaining}}</i>-->
                    </span>
                </div>
                <div class="uploader-file-actions">
                    <ui-tab-btn name="删除" @click="remove"></ui-tab-btn>
                    <!--<ui-btn name="删除" icon="icon trash alternate" @click="remove"></ui-btn>-->
                    <!--<ui-btn name="暂停" icon="icon pause" @click="pause"></ui-btn>-->
                    <!--<ui-btn name="开始" icon="icon play" @click="resume"></ui-btn>-->
                    <!--<ui-btn name="重试" icon="icon undo" @click="retry"></ui-btn>-->
                    <!--<span class="uploader-file-pause" @click="pause"></span>-->
                    <!--<span class="uploader-file-resume" @click="resume">️</span>-->
                    <!--<span class="uploader-file-retry" @click="retry"></span>-->
                    <!--<span class="uploader-file-remove" @click="remove"></span>-->
                </div>
            </div>
        </template>
    </div>
</template>
<script>
    import Uploader from 'simple-uploader.js'
    import events from '../common/file-events'
    import { secondsToStr } from '../common/utils'

    const COMPONENT_NAME = 'uploader-file'

    export default {
        name: COMPONENT_NAME,
        props: {
            file: {
                type: Object,
                default() {
                    return {}
                }
            },
            list: {
                type: Boolean,
                default: false
            }
        },
        data() {
            return {
                paused: false,
                error: false,
                averageSpeed: 0,
                currentSpeed: 0,
                isComplete: false,
                isUploading: false,
                size: 0,
                formatedSize: '',
                uploadedSize: 0,
                progress: 0,
                timeRemaining: 0,
                type: '',
                extension: '',
                progressingClass: '',
            }
        },
        computed: {
            fileCategory() {
                const extension = this.extension
                const isFolder = this.file.isFolder
                let type = isFolder ? 'folder' : 'unknown'
                const categoryMap = this.file.uploader.opts.categoryMap
                const typeMap = categoryMap || {
                    image: ['gif', 'jpg', 'jpeg', 'png', 'bmp', 'webp'],
                    video: ['mp4', 'm3u8', 'rmvb', 'avi', 'swf', '3gp', 'mkv', 'flv'],
                    audio: ['mp3', 'wav', 'wma', 'ogg', 'aac', 'flac'],
                    document: [
                        'doc',
                        'txt',
                        'docx',
                        'pages',
                        'epub',
                        'pdf',
                        'numbers',
                        'csv',
                        'xls',
                        'xlsx',
                        'keynote',
                        'ppt',
                        'pptx'
                    ]
                }
                Object.keys(typeMap).forEach(_type => {
                    const extensions = typeMap[_type]
                    if (extensions.indexOf(extension) > -1) {
                        type = _type
                    }
                })
                return type
            },
            iconClass() {
                switch(this.fileCategory){
                case 'image':
                    return 'file image t-primary'
                case 'video':
                    return 'file video t-success'
                case 'audio':
                    return 'file audio t-warning'
                case 'folder':
                    return 'folder'
                case 'document':
                    return 'book t-success'
                default:
                    return 'file'
                }
            },
            progressStyle() {
                const progress = Math.floor(this.progress * 100)
                const style = `translateX(${Math.floor(progress - 100)}%)`
                return {
                    progress: `${progress}%`,
                    webkitTransform: style,
                    mozTransform: style,
                    msTransform: style,
                    transform: style
                }
            },
            formatedAverageSpeed() {
                return `${Uploader.utils.formatSize(this.averageSpeed)}/s`
            },
            status() {
                const isUploading = this.isUploading
                const isComplete = this.isComplete
                const isError = this.error
                const paused = this.paused
                if (isComplete) {
                    return 'success'
                }else if (isError) {
                    return 'error'
                }else if (isUploading) {
                    return 'uploading'
                }else if (paused) {
                    return 'paused'
                }
                return 'waiting'
            },
            statusText() {
                const status = this.status
                const text = this.file.uploader.fileStatusText[status] || status
                /*switch(status){
                case 'waiting':
                    return `<span class="ui small label">${text}</span>`
                case 'uploading':
                    return `<span class="ui teal small label"><i class="icon circle notch loading-icon"></i> ${text}</span>`
                case 'error':
                    return `<span class="ui red small label">${text}</span>`
                case 'success':
                    return `<span class="ui green small label">${text}</span>`
                default:
                    return ''
                }*/
                switch(status){
                case 'waiting':
                    return { type: "info", text:text }
                case 'uploading':
                    return { type: "", text: text }
                case 'error':
                    return { type: "danger", text: text }
                case 'success':
                    return { type: "success", text: text }
                default:
                    return ''
                }
            },
            formatedTimeRemaining() {
                const timeRemaining = this.timeRemaining
                const file = this.file
                if (timeRemaining === Number.POSITIVE_INFINITY || timeRemaining === 0) {
                    return ''
                }
                let parsedTimeRemaining = secondsToStr(timeRemaining)
                const parseTimeRemaining = file.uploader.opts.parseTimeRemaining
                if (parseTimeRemaining) {
                    parsedTimeRemaining = parseTimeRemaining(timeRemaining, parsedTimeRemaining)
                }
                return parsedTimeRemaining
            }
        },
        watch: {
            status(newStatus, oldStatus) {
                if (oldStatus && newStatus === 'uploading' && oldStatus !== 'uploading') {
                    this.tid = setTimeout(() => {
                        this.progressingClass = 'uploader-file-progressing'
                    }, 200)
                }else{
                    clearTimeout(this.tid)
                    this.progressingClass = ''
                }
            }
        },
        methods: {
            _actionCheck() {
                this.paused = this.file.paused
                this.error = this.file.error
                this.isUploading = this.file.isUploading()
            },
            pause() {
                this.file.pause()
                this._actionCheck()
                this._fileProgress()
            },
            resume() {
                this.file.resume()
                this._actionCheck()
            },
            remove() {
                this.file.cancel()
            },
            retry() {
                this.file.retry()
                this._actionCheck()
            },
            fileEventsHandler(event, args) {
                const rootFile = args[0]
                const file = args[1]
                const target = this.list ? rootFile : file
                if (this.file === target) {
                    if (this.list && event === 'fileSuccess') {
                        return
                    }
                    this[`_${event}`].apply(this, args)
                }
            },
            _fileProgress() {
                this.progress = this.file.progress()
                this.averageSpeed = this.file.averageSpeed
                this.currentSpeed = this.file.currentSpeed
                this.timeRemaining = this.file.timeRemaining()
                this.uploadedSize = this.file.sizeUploaded()
                this._actionCheck()
            },
            _fileSuccess() {
                this._fileProgress()
                this.error = false
                this.isComplete = true
                this.isUploading = false
            },
            _fileComplete() {
                this._fileSuccess()
            },
            _fileError() {
                this._fileProgress()
                this.error = true
                this.isComplete = false
                this.isUploading = false
            },
            fileType(type) {
                if (type.indexOf('excel') >= 0) return 'excel'
                if (type.indexOf('sheet') >= 0) return 'excel'
                if (type.indexOf('word') >= 0) return 'word'
                if (type.indexOf('powerpoint') >= 0) return 'ppt'
                let last = type.split('.').length - 1
                return type.split('.')[last]
            }
        },
        mounted() {
            const staticProps = ['paused', 'error', 'averageSpeed', 'currentSpeed']
            const fnProps = [
                'isComplete',
                'isUploading',
                {
                    key: 'size',
                    fn: 'getSize'
                },
                {
                    key: 'formatedSize',
                    fn: 'getFormatSize'
                },
                {
                    key: 'uploadedSize',
                    fn: 'sizeUploaded'
                },
                'progress',
                'timeRemaining',
                {
                    key: 'type',
                    fn: 'getType'
                },
                {
                    key: 'extension',
                    fn: 'getExtension'
                }
            ]
            staticProps.forEach(prop => {
                this[prop] = this.file[prop]
            })
            fnProps.forEach(fnProp => {
                if (typeof fnProp === 'string') {
                    this[fnProp] = this.file[fnProp]()
                }else{
                    this[fnProp.key] = this.file[fnProp.fn]()
                }
            })

            const handlers = (this._handlers = {})
            const eventHandler = event => {
                handlers[event] = (...args) => {
                    this.fileEventsHandler(event, args)
                }
                return handlers[event]
            }
            events.forEach(event => {
                this.file.uploader.on(event, eventHandler(event))
            })
        },
        destroyed() {
            events.forEach(event => {
                this.file.uploader.off(event, this._handlers[event])
            })
            this._handlers = null
        }
    }
</script>
<style lang="scss" scoped>
    .uploader-file{
        position:relative;
        height:49px;
        line-height:49px;
        overflow:hidden;
        border-bottom:1px solid #eee;
        font-size:14px;
        color:rgba(#000, 0.6);
    }
    .uploader-file[status='waiting'] .uploader-file-pause,
    .uploader-file[status='uploading'] .uploader-file-pause{
        display:block;
    }
    .uploader-file[status='paused'] .uploader-file-resume{
        display:block;
    }
    .uploader-file[status='error'] .uploader-file-retry{
        display:block;
    }
    .uploader-file[status='success'] .uploader-file-remove{
        display:none;
    }
    .uploader-file[status='error'] .uploader-file-progress{
        background:#ffe0e0;
    }
    .uploader-file-progress{
        border-bottom:1px #fff solid;
        position:absolute;
        width:100%;
        height:100%;
        background:#e2eeff;
        transform:translateX(-100%);
    }
    .uploader-file-progressing{
        transition:all 0.4s linear;
    }
    .uploader-file-info{
        position:relative;
        z-index:1;
        height:100%;
        overflow:hidden;
    }
    .uploader-file-info:hover{
        background-color:rgba(240, 240, 240, 0.2);
    }
    .uploader-file-info i,
    .uploader-file-info em{
        font-style:normal;
    }
    .uploader-file-name,
    .uploader-file-size,
    .uploader-file-type,
    .uploader-file-meta,
    .uploader-file-status,
    .uploader-file-actions{
        /*float: left;*/
        position:relative;
        height:100%;
        padding:0 10px;
    }
    .uploader-file-name{
        /*width: 40%;*/
        overflow:hidden;
        white-space:nowrap;
        text-overflow:ellipsis;
    }
    .file-icon{
        margin-top:13px !important;
        margin-right:8px !important;
        width:24px !important;
        height:24px !important;
        display:inline-block;
        vertical-align:top;
        color:#999;
        &::before{
            display:block;
            height:100%;
            font-size:20px;
            line-height:25px;
            text-indent:0;
        }
    }
    .uploader-file-icon{
        width:24px;
        height:24px;
        display:inline-block;
        vertical-align:top;
        margin-top:13px;
        margin-right:8px;
    }
    .uploader-file-icon::before{
        content:'📃';
        display:block;
        height:100%;
        font-size:18px;
        line-height:1;
        text-indent:0;
    }
    .uploader-file-icon[icon='folder']::before{
        content:'📂';
    }
    .uploader-file-icon[icon='image']::before{
        content:'📷';
    }
    .uploader-file-icon[icon='video']::before{
        content:'📹';
    }
    .uploader-file-icon[icon='audio']::before{
        content:'🎵';
    }
    .uploader-file-icon[icon='document']::before{
        content:'📋';
    }
    .uploader-file-type{
        width:100px;
    }
    .uploader-file-size{
        width:100px;
    }
    .uploader-file-meta{
        width:8%;
    }
    .uploader-file-status{
        width:150px;
    }
    .uploader-file-actions{
        width:70px;
        text-align:right;
    }
    .uploader-file-actions > span{
        display:none;
        float:left;
        width:16px;
        height:16px;
        margin-top:16px;
        margin-right:10px;
        cursor:pointer;
        background:url('') no-repeat 0 0;
    }
    .uploader-file-actions > span:hover{
        background-position-x:-21px;
    }
    .uploader-file-actions .uploader-file-pause{
        background-position-y:0;
    }
    .uploader-file-actions .uploader-file-resume{
        background-position-y:-17px;
    }
    .uploader-file-actions .uploader-file-retry{
        background-position-y:-53px;
    }
    .uploader-file-actions .uploader-file-remove{
        display:block;
        background-position-y:-34px;
    }
</style>
